home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software of the Month Club 1996 June
/
Software of the Month Club 1996 June.iso
/
pc
/
dos
/
dtp
/
display
/
drvsrc
/
ati_16md.asm
< prev
next >
Wrap
Assembly Source File
|
1994-05-14
|
16KB
|
578 lines
;--------------------------------------------------------------------------
; This is file ATI_16M.ASM, Version 0.3
;
; Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
; Copyright (C) 1992 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221
; Copyright (C) 1994 Bernhard Schwall (ATI-parts)
;
; This file is distributed under the terms listed in the document
; "copying.dj", available from DJ Delorie at the address above.
; A copy of "copying.dj" should accompany this file; if not, a copy
; should be available from where this file was obtained. This file
; may not be distributed without a verbatim copy of "copying.dj".
;
; This file is distributed WITHOUT ANY WARRANTY; without even the implied
; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
;--------------------------------------------------------------------------
;
; changes:
;
; Version 0.1: 07.02.1994
; first release
;
; Version 0.2: 09.02.1994
; fixed the byte/line to really needed size, so 640x480x16.7mio
; will fit in 1MB-Ram
; clear 2.MB when using 16.7mio. colormode
;
; Version 0.3: 16.02.1994
; return the right number of planes
; changed 24 bit mode to BGR-order
; so disp160 will run in truecolor
;
; Version 0.31: 31.03.1994
; set screenwidth to original value when switching to textmode
; changed the standard setup: disable memory aperture
; changed grdriver.inc to new verson shipped with LIBGRX 1.03 which
; now uses disp180 too.
;
;--------------------------------------------------------------------------
include grdriver.inc
cseg segment byte public 'code'
assume cs:cseg, ds:cseg, es:cseg, ss:nothing
;--------------------------------------------------------------------------
; DRIVER HEADER
; The following entries MUST match the structure and constant
; declarations in the file 'grdriver.h' of the GRX graphics library
; The mode word should contain the following bitfields:
; - the GRD_NEW_DRIVER bit set for any new format driver
; - the adapter type field should be specified
; - the memory size field should be specified
; - the paging mode field should be specified
; The mode set routine will OR in the plane bitfield as it will
; change when different color number modes are requested.
;--------------------------------------------------------------------------
dw offset mode_set_routine
dw offset paging_routine
mode_W dw GRD_NEW_DRIVER+GRD_VGA+GRD_1024K+GRD_RW_64K
;
; The 'def_xx' fields are filled in by go32 from the corresponding
; fields of the 'GO32' environment variable
;
def_tw dw 80 ; text width
def_th dw 25 ; text height
def_gw dw 640 ; graphics width
def_gh dw 480 ; graphics height
def_nc dw 16 ; graphics colors
dw offset driver_init_routine
dw offset text_mode_table
dw offset graphics_mode_table
;
; Biggest text and graphics sizes
;
Max_TW equ 80
Max_TH equ 50
Max_GWn equ 800 ; non interlaced!!!
Max_GHn equ 600
Max_GW equ 1024 ; may be interlaced
Max_GH equ 768
;--------------------------------------------------------------------------
; TABLE OF SUPPORTED TEXT MODES
; - keep sorted by size
; - end with an all 0 entry
; - BIOS field = 0xff disables it
; - fields:
; width, height, colors, BIOS#+ setup_procedure_index*256
;--------------------------------------------------------------------------
text_mode_table label word
dw 80, 25, 2, 007h + 00000h
dw 40, 25, 16, 001h + 00000h
dw 80, 25, 16, 003h + 00000h
dw 80, 28, 16, 003h + 00100h
dw 80, 50, 16, 003h + 00200h
dw 132, 25, 16, 023h + 00000h
dw 132, 28, 16, 023h + 00100h
dw 132, 44, 16, 033h + 00000h
dw 0, 0, 0, 000h + 00000h
;--------------------------------------------------------------------------
; TABLE OF SUPPORTED GRAPHICS MODES
; - keep sorted first by colors then by size
; - end with an all 0 entry
; - BIOS field = 0xff disables it
; - fields:
; width, height, colors, BIOS#+ setup_procedure_index*256
;--------------------------------------------------------------------------
graphics_mode_table label word
dw 320, 200, 16, 00dh + 00000h
dw 640, 200, 16, 00eh + 00000h
dw 640, 350, 16, 010h + 00000h
dw 640, 480, 16, 012h + 00000h
dw 800, 600, 16, 054h + 00000h
dw 1024, 768, 16, 055h + 00000h
dw 320, 200, 256, 013h + 00000h
dw 640, 400, 256, 061h + 00000h
dw 640, 480, 256, 062h + 00000h
dw 800, 600, 256, 063h + 00000h
dw 1024, 768, 256, 064h + 00000h
dw 640, 480, 32768, 062h + 00300h
dw 800, 600, 32768, 063h + 00300h
dw 1024, 768, 32768, 064h + 00300h
dw 640, 480, 49168, 062h + 00310h ; 49168 = 0xc000+16
dw 800, 600, 49168, 063h + 00310h
dw 1024, 768, 49168, 064h + 00310h
dw 640, 480, 49176, 062h + 00380h ; 49176 = 0xc000+24
dw 800, 600, 49176, 063h + 00380h
dw 0, 0, 0, 000h + 00000h
;--------------------------------------------------------------------------
; TABLE OF SPECIAL SETUP PROCEDURES
; You may need such procedures for:
; -- reloading fonts on standard EGA or VGA for
; higher resolution text modes
; -- enable HiColor mode of some Super VGAs
; -- Handle the parameter passing conventions of the VESA BIOS
; -- put VGA into 256 color plane mode ("MODE X")
; -- etc...
; There should be one entry in the table for every non-zero
; 'setup_procedure_index' in the text and graphics mode tables.
; The first entry in the table belongs to index 100h, and so on.
; The special setup procedure is invoked via a near call.
;
; Entry: DI=address of the mode record from the text or graphics
; table to set up.
;
; Exit: Adapter configured
; BX=driver mode word as it should be returned by the mode set
; routine. Typically it involves picking up the mode word
; from the header and OR-ing in the appropriate bitplane mode
; bitfield. (This is not needed for text modes)
; AX, SI can be trashed, PRESERVE DI!!!!
;
; NOTE: This runs in real mode, but don't mess with the segment registers.
;--------------------------------------------------------------------------
special_setup_table label word
dw offset VGA_28row_mode_set
dw offset VGA_50row_mode_set
dw offset ATI_setup ; setup 15, 16 and 24 bit
;
; Routine to set up VGA 50 row mode
; interface is described above
;
VGA_50row_mode_set proc near
mov ax,03h ; set 80x25 mode
int 10h
xor bx,bx
mov ax,1112h ; load 8x8 font
int 10h
ret
VGA_50row_mode_set endp
VGA_28row_mode_set proc near
mov ax,WORD PTR [di+6] ; set 25 line mode
xor ah,ah
int 10h
xor bx,bx
mov ax,1111h ; load 8x14 font
int 10h
ret
VGA_28row_mode_set endp
; Routine to initialize 16.7milion color mode on ATI GU+ GUpro
ATI_Accell db 0
ATI_lo dw 0
ATI_hi dw 0
ATI_setup proc near
mov ax,word ptr [di+6]
and ax,006fh
int 10h ; switch to graphicsmode
mov cx,ax
and ax,006fh
cmp ax,63h
jl No2MB
mov dx,01ceh ; get old value of ATI2E
mov al,0aeh
out dx,al
inc dx
in al,dx
and al,0f0h
or al,05
out dx,al ; set read/write-bank to 2.MB
mov ax,cx
int 10h ; switch to graphicsmode second time
; to clear 2.MB
mov dx,01ceh ; get old value of ATI2E
mov al,0aeh
out dx,al
inc dx
in al,dx
and al,0f0h
out dx,al ; set read/write-bank to 1.MB
No2MB: mov dx,52eeh
in ax,dx
and ax,007fh
mov cl,7
shl ax,cl
add ax,0c000h
mov ATI_hi,ax
mov ax,0064h
mov ATI_lo,ax ; get Rom-Entry-Point
; select colordepth
mov cl,byte ptr [di+6]
test cl,80h
jz No_888
mov ah,07h ; 888
mov bx,GRD_24_PLANES
push bx
jmp SelRes
No_888: test cl,10h
jz No_565
mov ah,0dh ; 565
mov bx,GRD_16_R_PLANES
push bx
jmp SelRes
No_565: mov ah,05h ; 555
mov bx,GRD_16_PLANES
push bx
; select resolution
SelRes: and cl,6fh
cmp cl,62h
jnz No640
mov al,21h ; 640x480
jmp SetRes
No640: cmp cl,63h
jnz No800
mov al,01h ; 800x600
jmp SetRes
No800: mov al,41h ; 1024x768
SetRes: mov bx,3
call dword ptr [ATI_lo] ; set resolution and colordepth
mov ax,0068h
mov ATI_lo,ax
mov ax,1
call dword ptr [ATI_lo] ; initialize video mode
mov dx,5eeeh
; mov al,02h ; enable memory-aperture
mov al,00h ; disable memory-aperture
; mov ah,09h ; memory aperture at MB 9
out dx,ax
mov ax,word ptr [di]
shr ax,3
mov dx,26eeh
out dx,ax
mov dx,76eeh
out dx,ax
mov ATI_Accell,1
pop bx ; driver mode word
; mov bx,GRD_16_PLANES ; comment out to use with disp180
or bx,mode_W
mov ax,0
ret
ATI_setup endp
; switch ATI to SVGA-compatilbe mode
ATI_DisableAccell proc near
mov dx,52eeh
in ax,dx
and ax,007fh
mov cl,7
shl ax,cl
add ax,0c000h
mov ATI_hi,ax
mov ax,0064h
mov ATI_lo,ax
mov ax,0
mov bx,3
call dword ptr [ATI_lo]
mov ax,0068h
mov ATI_lo,ax
mov ax,0
call dword ptr [ATI_lo]
mov dx,5eeeh
mov ax,0900h ; memory aperture disabled
out dx,ax
mov dx,01ceh ; get old value of ATI2E
mov al,0aeh
out dx,al
inc dx
in al,dx
and al,0f0h
out dx,al ; set read/write-bank to 1.MB
mov ax,1024 ; set screenwidth to 1024 (original value)
shr ax,3
mov dx,26eeh
out dx,ax
mov dx,76eeh
out dx,ax
mov ATI_Accell,0
ret
ATI_DisableAccell endp
;--------------------------------------------------------------------------
; DRIVER INIT ROUTINE
; called once after the driver is loaded
; may do one or more of the followings:
; - check for proper board type
; - check amount of RAM on board, and:
; -- update word in header to reflect correct amount
; -- disable modes in the tables for which there is not enough RAM
; - check for special equipment (HiColor DAC, etc...)
;
; Entry: nothing
;
; Exit: AX=status:
; non-zero: OK,
; 0: something went wrong (e.g. wrong adapter, etc..)
; BX,CX,DX may be trashed
;
; NOTE: This runs in real mode, but don't mess with the segment registers.
;--------------------------------------------------------------------------
driver_init_routine proc far
mov ax,1
ret
driver_init_routine endp
;--------------------------------------------------------------------------
; MODE SET ROUTINE
; sets up a text or graphics mode as close as possible to the one
; reguested by the user with regard to number of colors and size.
;
; Entry: AX=mode selection
; 0 = 80x25 text
; 1 = default text
; 2 = text CX cols by DX rows
; 3 = biggest text
; 4 = 320x200 graphics
; 5 = default graphics
; 6 = graphics CX width by DX height
; 7 = biggest non-interlaced graphics
; 8 = biggest graphics
; 9 = graphics BX colors, CX width by DX height
;
; Exit: BX=driver mode flag
; CX=width (in pixels or characters)
; DX=height
;
; NOTE: This runs in real mode, but don't mess with the segment registers.
; YOU SHOULD NOT NEED TO CHANGE THIS ROUTINE AS IT IS PRETTY
; MUCH TABLE DRIVEN
;--------------------------------------------------------------------------
mode_set_routine proc far
push ds
push di
push si
mov si,cs
mov ds,si
cmp ax,9
jbe DoIt
jmp Exit
DoIt: add ax,ax
mov si,ax
jmp WORD PTR mode_set_table[si]
mode_set_table label word
dw offset mode_0
dw offset mode_1
dw offset mode_2
dw offset mode_3
dw offset mode_4
dw offset mode_5
dw offset mode_6
dw offset mode_7
dw offset mode_8
dw offset mode_9
mode_0: mov si,offset text_mode_table ; 80x25 text
mov bx,def_nc
mov cx,80
mov dx,25
jmp Lookup
mode_1: mov si,offset text_mode_table ; default text
mov bx,def_nc
mov cx,def_tw
mov dx,def_th
jmp Lookup
mode_2: mov si,offset text_mode_table ; CX*DX text
mov bx,def_nc
jmp Lookup
mode_3: mov si,offset text_mode_table ; biggest text
mov bx,def_nc
mov cx,Max_TW
mov dx,Max_TH
jmp Lookup
mode_4: mov si,offset graphics_mode_table ; 320x200 graphics
mov bx,def_nc
mov cx,320
mov dx,200
jmp Lookup
mode_5: mov si,offset graphics_mode_table ; default graphics
mov bx,def_nc
mov cx,def_gw
mov dx,def_gh
jmp Lookup
mode_6: mov si,offset graphics_mode_table ; CX*DX graphics
mov bx,def_nc
jmp Lookup
mode_7: mov si,offset graphics_mode_table ; biggest non-interlaced gr
mov bx,def_nc
mov cx,Max_GWn
mov dx,Max_GHn
jmp Lookup
mode_8: mov si,offset graphics_mode_table ; biggest graphics
mov bx,def_nc
mov cx,Max_GW
mov dx,Max_GH
jmp Lookup
mode_9: mov si,offset graphics_mode_table ; CX*DX graphics w/ BX colors
;
; At this point:
; SI points to the table to search (text or graphics)
; BX has colors
; CX has width
; DX has height
;
Lookup: xor ax,ax ; last color number seen
Find_C: cmp [si+4],ax ; last color number == this?
je Same_C
jb Prev_C ; end of table -- use last color
cmp BYTE PTR [si+6],0ffh ; valid entry ?
je Prev_C ; not -- use last color
mov ax,[si+4] ; record color number
mov di,si ; start of entries w/ this color
cmp ax,bx ; enough colors ?
jae Find_S
Same_C: add si,8
jmp Find_C
Prev_C: or ax,ax ; found any color at all?
je Exit
;
; At this point:
; DI points into the table to the first entry with the desired color
; number (either it has enough colors or it is the highest color
; number supported by the driver). Additionally, at least the
; first (= smallest size) entry for this color is valid (has a
; valid BIOS number).
; AX has the color number adjusted for the driver
; CX has width
; DX has height
;
Find_S: cmp [di+4],ax ; still the same color #?
jne Prev_S
cmp BYTE PTR [di+6],0ffh ; valid entry ?
je Prev_S
cmp [di],cx
jb Next_S
cmp [di+2],dx
jae GotIt
Next_S: add di,8
jmp Find_S
Prev_S: sub di,8
;
; At this point:
; DI points to the table entry we want to set up
;
GotIt: mov ax,[di+6] ; BIOS mode number
or ah,ah ; special ?
je doBIOS
mov al,ah
xor ah,ah
dec ax
add ax,ax
mov si,ax
call WORD PTR special_setup_table[si]
jmp RetVal
doBIOS:
;--------------- changed because AccellChip must be disabled if not used
push ax
mov al,ATI_Accell
cmp al,0
jz NoATI
call ATI_DisableAccell
NoATI: pop ax
;--------------- change end
int 10h
mov bx,GRD_1_PLANE
cmp WORD PTR [di+4],2 ; 2 colors ?
je doFLAG
mov bx,GRD_4_PLANES
cmp WORD PTR [di+4],16 ; 16 colors ?
je doFLAG
mov bx,GRD_8_PLANES
cmp WORD PTR [di+4],256 ; 256 colors ?
je doFLAG
mov bx,GRD_16_PLANES
cmp WORD PTR [di+4],32768 ; 32K colors ?
je doFLAG
mov bx,GRD_PLANE_MASK ; something is wrong!!
doFLAG: or bx,mode_W
RetVal: mov cx,[di]
mov dx,[di+2]
Exit: pop si
pop di
pop ds
ret
mode_set_routine endp
;--------------------------------------------------------------------------
; PAGING ROUTINE
;
; Entry: AH=read page
; AL=write page
;
; Exit: VGA configured.
; AX,BX,CX,DX,SI,DI may be trashed
;
; NOTE: This runs in protected mode! Don't mess with the segment registers!
; This code must be relocatable and may not reference any data!
;--------------------------------------------------------------------------
assume ds:nothing, es:nothing
paging_routine proc far
mov bx,ax ; save ax;
; can't speed up by using only 1MB for SVGA-modes because test itself
; would be to slow (data referenze not possible)
; set bits 4 and 5 of read/write bank to access 2.-4. MB
and al,30h
shr al,4
and ah,30h
shr ah,2
or ah,al ; combine Read and Write-Planes
cmp ah,0
mov dx,01ceh ; get old value of ATI2E
mov al,0aeh
out dx,al
inc dx
in al,dx
and al,0f0h
or al,ah
out dx,al ; write new value
and bh,0fh ; Read-plane on bits 0-3
mov ah,bh
shr ah,3 ; move bit 3 to bit 0;
shl bh,5 ; move bits 0-2 to 5-7;
or ah,bh
and bl,0fh ; Write-plane on bits 0-3
shl bl,1
or ah,bl ; Combine Read and Write plane
mov dx,01ceh ; ATI register
mov al,0b2h ; plane select
out dx,ax
ret
paging_routine endp
cseg ends
end